package handler

import (
	"fmt"
	"net/http"
	"strconv"
	"time"

	"apiGateWay/internal/config"
	"apiGateWay/internal/database"
	"apiGateWay/internal/model"
	"apiGateWay/internal/repository"
	"apiGateWay/pkg/logger"

	"github.com/gin-gonic/gin"
)

// AdminHandlerV2 管理接口处理器（使用数据库）
type AdminHandlerV2 struct {
	cfg            *config.Config
	routeRepo      repository.RouteRepository
	logRepo        repository.LogRepository
	configRepo     repository.ConfigRepository
	useDatabase    bool
}

// NewAdminHandlerV2 创建管理处理器
func NewAdminHandlerV2(cfg *config.Config) *AdminHandlerV2 {
	handler := &AdminHandlerV2{
		cfg:         cfg,
		useDatabase: cfg.Database.Enabled && database.DB != nil,
	}

	if handler.useDatabase {
		handler.routeRepo = repository.NewRouteRepository(database.DB)
		handler.logRepo = repository.NewLogRepository(database.DB)
		handler.configRepo = repository.NewConfigRepository(database.DB)
	}

	return handler
}

// GetRoutes 获取所有路由（仅从数据库）
func (h *AdminHandlerV2) GetRoutes(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法获取路由"})
		return
	}

	routes, err := h.routeRepo.GetAll()
	if err != nil {
		logger.Errorf("获取路由失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取路由失败"})
		return
	}

	// 直接返回扁平结构，方便前端使用
	result := make([]gin.H, len(routes))
	for i, route := range routes {
		result[i] = gin.H{
			"id":            strconv.FormatUint(uint64(route.ID), 10),
			"name":          route.Name,
			"path":          route.Path,
			"target":        route.Target,
			"methods":       []string(route.Methods),
			"auth_required": route.AuthRequired,
			"rate_limit": gin.H{
				"enabled": route.RateLimitQPS > 0 || route.RateLimitBurst > 0,
				"qps":     route.RateLimitQPS,
				"burst":   route.RateLimitBurst,
			},
			"is_enabled": route.IsEnabled,
		}
	}
	c.JSON(http.StatusOK, result)
}

// CreateRoute 创建路由（仅使用数据库）
func (h *AdminHandlerV2) CreateRoute(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法创建路由"})
		return
	}

	var routeReq config.RouteConfig
	if err := c.ShouldBindJSON(&routeReq); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数"})
		return
	}

	route := &model.Route{
		Name:         routeReq.Name,
		Path:         routeReq.Path,
		Target:       routeReq.Target,
		Methods:      routeReq.Methods,
		AuthRequired: routeReq.AuthRequired,
		IsEnabled:    true,
	}
	if routeReq.RateLimit.Enabled {
		route.RateLimitQPS = routeReq.RateLimit.QPS
		route.RateLimitBurst = routeReq.RateLimit.Burst
	}

	if err := h.routeRepo.Create(route); err != nil {
		logger.Errorf("创建路由失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建路由失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "路由创建成功",
		"id":      strconv.FormatUint(uint64(route.ID), 10),
		"route": RouteResponse{
			ID:          strconv.FormatUint(uint64(route.ID), 10),
			RouteConfig: routeReq,
		},
	})
}

// UpdateRoute 更新路由（仅使用数据库）
func (h *AdminHandlerV2) UpdateRoute(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法更新路由"})
		return
	}

	id := c.Param("id")
	routeID, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的路由 ID"})
		return
	}

	route, err := h.routeRepo.GetByID(uint(routeID))
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "路由不存在"})
		return
	}

	var routeReq config.RouteConfig
	if err := c.ShouldBindJSON(&routeReq); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数"})
		return
	}

	route.Name = routeReq.Name
	route.Path = routeReq.Path
	route.Target = routeReq.Target
	route.Methods = routeReq.Methods
	route.AuthRequired = routeReq.AuthRequired
	if routeReq.RateLimit.Enabled {
		route.RateLimitQPS = routeReq.RateLimit.QPS
		route.RateLimitBurst = routeReq.RateLimit.Burst
	} else {
		route.RateLimitQPS = 0
		route.RateLimitBurst = 0
	}

	if err := h.routeRepo.Update(route); err != nil {
		logger.Errorf("更新路由失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新路由失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "路由更新成功",
		"route": RouteResponse{
			ID:          id,
			RouteConfig: routeReq,
		},
	})
}

// DeleteRoute 删除路由（仅使用数据库）
func (h *AdminHandlerV2) DeleteRoute(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法删除路由"})
		return
	}

	id := c.Param("id")
	routeID, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的路由 ID"})
		return
	}

	if err := h.routeRepo.Delete(uint(routeID)); err != nil {
		logger.Errorf("删除路由失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除路由失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "路由删除成功"})
}

// GetLogs 获取日志（仅从数据库）
func (h *AdminHandlerV2) GetLogs(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法获取日志"})
		return
	}

	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "20"))
	level := c.Query("level")
	
	var startTime, endTime *time.Time
	if startStr := c.Query("startTime"); startStr != "" {
		if t, err := time.Parse(time.RFC3339, startStr); err == nil {
			startTime = &t
		}
	}
	if endStr := c.Query("endTime"); endStr != "" {
		if t, err := time.Parse(time.RFC3339, endStr); err == nil {
			endTime = &t
		}
	}

	params := repository.LogQueryParams{
		Page:      page,
		PageSize:  pageSize,
		Level:     level,
		StartTime: startTime,
		EndTime:   endTime,
	}

	logs, total, err := h.logRepo.List(params)
	if err != nil {
		logger.Errorf("获取日志失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取日志失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"list":     logs,
		"total":    total,
		"page":     page,
		"pageSize": pageSize,
	})
}

// GetAuthConfig 获取认证配置（从数据库）
func (h *AdminHandlerV2) GetAuthConfig(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法获取配置"})
		return
	}

	// 从数据库读取 JWT 配置
	jwtConfig, err := h.configRepo.GetByKey("jwt")
	if err != nil {
		logger.Warnf("从数据库获取 JWT 配置失败，使用默认配置: %v", err)
		c.JSON(http.StatusOK, gin.H{
			"jwt":    h.cfg.JWT,
			"oauth2": h.cfg.OAuth2,
		})
		return
	}

	// 从数据库读取 OAuth2 配置（如果存在）
	oauth2Config, _ := h.configRepo.GetByKey("oauth2")

	result := gin.H{}
	if jwtConfig != nil && jwtConfig.Value != nil {
		result["jwt"] = jwtConfig.Value
	} else {
		result["jwt"] = h.cfg.JWT
	}

	if oauth2Config != nil && oauth2Config.Value != nil {
		result["oauth2"] = oauth2Config.Value
	} else {
		result["oauth2"] = h.cfg.OAuth2
	}

	c.JSON(http.StatusOK, result)
}

// UpdateAuthConfig 更新认证配置（保存到数据库）
func (h *AdminHandlerV2) UpdateAuthConfig(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法更新配置"})
		return
	}

	var req struct {
		JWT    map[string]interface{} `json:"jwt"`
		OAuth2 map[string]interface{} `json:"oauth2"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数"})
		return
	}

	// 更新 JWT 配置
	if req.JWT != nil {
		jwtConfig := &model.SystemConfig{
			Key:      "jwt",
			Category: "auth",
			Value:    req.JWT,
		}
		if err := h.configRepo.CreateOrUpdate(jwtConfig); err != nil {
			logger.Errorf("保存 JWT 配置失败: %v", err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "保存配置失败"})
			return
		}
	}

	// 更新 OAuth2 配置
	if req.OAuth2 != nil {
		oauth2Config := &model.SystemConfig{
			Key:      "oauth2",
			Category: "auth",
			Value:    req.OAuth2,
		}
		if err := h.configRepo.CreateOrUpdate(oauth2Config); err != nil {
			logger.Errorf("保存 OAuth2 配置失败: %v", err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "保存配置失败"})
			return
		}
	}

	logger.Info("认证配置已更新到数据库")
	c.JSON(http.StatusOK, gin.H{"message": "配置更新成功"})
}

// GetRateLimitConfig 获取限流配置（从数据库）
func (h *AdminHandlerV2) GetRateLimitConfig(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法获取配置"})
		return
	}

	rateLimitConfig, err := h.configRepo.GetByKey("rate_limit")
	if err != nil {
		logger.Warnf("从数据库获取限流配置失败，使用默认配置: %v", err)
		c.JSON(http.StatusOK, h.cfg.RateLimit)
		return
	}

	if rateLimitConfig != nil && rateLimitConfig.Value != nil {
		c.JSON(http.StatusOK, rateLimitConfig.Value)
	} else {
		c.JSON(http.StatusOK, h.cfg.RateLimit)
	}
}

// UpdateRateLimitConfig 更新限流配置（保存到数据库）
func (h *AdminHandlerV2) UpdateRateLimitConfig(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法更新配置"})
		return
	}

	var rateLimit map[string]interface{}
	if err := c.ShouldBindJSON(&rateLimit); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数"})
		return
	}

	rateLimitConfig := &model.SystemConfig{
		Key:      "rate_limit",
		Category: "rate_limit",
		Value:    rateLimit,
	}

	if err := h.configRepo.CreateOrUpdate(rateLimitConfig); err != nil {
		logger.Errorf("保存限流配置失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存配置失败"})
		return
	}

	logger.Info("限流配置已更新到数据库")
	c.JSON(http.StatusOK, gin.H{"message": "配置更新成功"})
}

// GetSystemConfig 获取系统配置（从数据库）
func (h *AdminHandlerV2) GetSystemConfig(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法获取配置"})
		return
	}

	result := gin.H{}

	// 从数据库读取各项配置
	corsConfig, _ := h.configRepo.GetByKey("cors")
	securityConfig, _ := h.configRepo.GetByKey("security")

	if corsConfig != nil && corsConfig.Value != nil {
		result["cors"] = corsConfig.Value
	} else {
		result["cors"] = h.cfg.CORS
	}

	if securityConfig != nil && securityConfig.Value != nil {
		result["security"] = securityConfig.Value
	} else {
		result["security"] = h.cfg.Security
	}

	result["server"] = h.cfg.Server // Server 配置通常不需要动态修改

	c.JSON(http.StatusOK, result)
}

// UpdateSystemConfig 更新系统配置（保存到数据库）
func (h *AdminHandlerV2) UpdateSystemConfig(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法更新配置"})
		return
	}

	var req struct {
		CORS     map[string]interface{} `json:"cors"`
		Security map[string]interface{} `json:"security"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数"})
		return
	}

	// 更新 CORS 配置
	if req.CORS != nil {
		corsConfig := &model.SystemConfig{
			Key:      "cors",
			Category: "cors",
			Value:    req.CORS,
		}
		if err := h.configRepo.CreateOrUpdate(corsConfig); err != nil {
			logger.Errorf("保存 CORS 配置失败: %v", err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "保存配置失败"})
			return
		}
	}

	// 更新安全配置
	if req.Security != nil {
		securityConfig := &model.SystemConfig{
			Key:      "security",
			Category: "security",
			Value:    req.Security,
		}
		if err := h.configRepo.CreateOrUpdate(securityConfig); err != nil {
			logger.Errorf("保存安全配置失败: %v", err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "保存配置失败"})
			return
		}
	}

	logger.Info("系统配置已更新到数据库")
	c.JSON(http.StatusOK, gin.H{"message": "配置更新成功"})
}

// ReloadConfig 重载配置
func (h *AdminHandlerV2) ReloadConfig(c *gin.Context) {
	logger.Info("配置重载请求")
	c.JSON(http.StatusOK, gin.H{"message": "配置重载成功"})
}

// GetStatistics 获取统计数据（从数据库）
func (h *AdminHandlerV2) GetStatistics(c *gin.Context) {
	if !h.useDatabase {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库未启用，无法获取统计"})
		return
	}

	// 统计总请求数
	var totalRequests int64
	database.DB.Model(&model.AuditLog{}).Count(&totalRequests)

	// 统计错误请求数
	var errorRequests int64
	database.DB.Model(&model.AuditLog{}).Where("status_code >= ?", 400).Count(&errorRequests)

	// 计算错误率
	errorRate := 0.0
	if totalRequests > 0 {
		errorRate = float64(errorRequests) / float64(totalRequests)
	}

	// 统计活跃连接（当前没有保存连接数据，返回0或从Prometheus获取）
	activeConnections := int64(0)

	// 统计最近24小时的请求趋势
	type TimeCount struct {
		Hour  int   `json:"hour"`
		Count int64 `json:"count"`
	}
	var hourlyStats []TimeCount
	now := time.Now()
	startTime := now.Add(-24 * time.Hour)

	database.DB.Model(&model.AuditLog{}).
		Where("created_at >= ?", startTime).
		Select("HOUR(created_at) as hour, COUNT(*) as count").
		Group("HOUR(created_at)").
		Scan(&hourlyStats)

	// 格式化小时数据（包含错误数）
	type HourlyErrorCount struct {
		Hour  int
		Count int64
	}
	var hourlyErrors []HourlyErrorCount
	database.DB.Model(&model.AuditLog{}).
		Where("created_at >= ? AND status_code >= 400", startTime).
		Select("HOUR(created_at) as hour, COUNT(*) as count").
		Group("HOUR(created_at)").
		Scan(&hourlyErrors)

	// 构建错误数映射
	errorMap := make(map[int]int64)
	for _, errStat := range hourlyErrors {
		errorMap[errStat.Hour] = errStat.Count
	}

	requestTrend := make([]gin.H, 0)
	for _, stat := range hourlyStats {
		requestTrend = append(requestTrend, gin.H{
			"time":     fmt.Sprintf("%02d:00", stat.Hour),
			"requests": stat.Count,
			"errors":   errorMap[stat.Hour],
		})
	}

	// 统计热门路由
	type RouteStats struct {
		Route       string  `json:"route"`
		Requests    int64   `json:"requests"`
		Errors      int64   `json:"errors"`
		AvgLatency  float64 `json:"avg_latency"`
	}
	var topRoutes []RouteStats

	database.DB.Model(&model.AuditLog{}).
		Where("created_at >= ?", startTime).
		Select("route, COUNT(*) as requests, SUM(CASE WHEN status_code >= 400 THEN 1 ELSE 0 END) as errors, AVG(request_time) as avg_latency").
		Group("route").
		Order("requests DESC").
		Limit(10).
		Scan(&topRoutes)

	// 统计延迟数据（P50/P95/P99）- MySQL 使用子查询方式
	type LatencyPercentile struct {
		P50 float64 `json:"p50"`
		P95 float64 `json:"p95"`
		P99 float64 `json:"p99"`
	}
	var latency LatencyPercentile

	// MySQL 计算百分位数的方法
	var totalLogs int64
	database.DB.Model(&model.AuditLog{}).
		Where("created_at >= ? AND request_time > 0", startTime).
		Count(&totalLogs)

	if totalLogs > 0 {
		// P50 - 中位数
		var p50Result struct {
			Value float64
		}
		database.DB.Raw(`
			SELECT request_time as value 
			FROM audit_logs 
			WHERE created_at >= ? AND request_time > 0 
			ORDER BY request_time 
			LIMIT 1 OFFSET ?
		`, startTime, totalLogs/2).Scan(&p50Result)
		latency.P50 = p50Result.Value

		// P95
		var p95Result struct {
			Value float64
		}
		database.DB.Raw(`
			SELECT request_time as value 
			FROM audit_logs 
			WHERE created_at >= ? AND request_time > 0 
			ORDER BY request_time 
			LIMIT 1 OFFSET ?
		`, startTime, int64(float64(totalLogs)*0.95)).Scan(&p95Result)
		latency.P95 = p95Result.Value

		// P99
		var p99Result struct {
			Value float64
		}
		database.DB.Raw(`
			SELECT request_time as value 
			FROM audit_logs 
			WHERE created_at >= ? AND request_time > 0 
			ORDER BY request_time 
			LIMIT 1 OFFSET ?
		`, startTime, int64(float64(totalLogs)*0.99)).Scan(&p99Result)
		latency.P99 = p99Result.Value
	}

	c.JSON(http.StatusOK, gin.H{
		"total_requests":     totalRequests,
		"error_requests":     errorRequests,
		"error_rate":         errorRate,
		"active_connections": activeConnections,
		"request_trend":      requestTrend,
		"top_routes":         topRoutes,
		"latency": latency,
	})
}


